package com.wxzhou.wangzhuan.service;

import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import okhttp3.ConnectionPool;
import okhttp3.Dispatcher;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import org.jboss.logging.Logger;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

@ApplicationScoped
public class OkHttpClientFactory {
    private static final Logger LOG = Logger.getLogger(OkHttpClientFactory.class);

    @Inject
    OkHttpConfig config;

    private OkHttpClient httpClient;
    private Semaphore globalSemaphore;
    private final ConcurrentHashMap<String, Semaphore> sourceSemaphores = new ConcurrentHashMap<>();

    public OkHttpClientFactory() {
        // 构造函数中不初始化 globalSemaphore，在 @PostConstruct 中初始化
    }

    @PostConstruct
    void initHttpClient() {
        // 初始化信号量
        this.globalSemaphore = new Semaphore(config.concurrentGlobal());

        // 构建连接池
        ConnectionPool connectionPool = new ConnectionPool(
                config.poolMaxIdle(),
                config.poolKeepAlive(),
                TimeUnit.MINUTES
        );

        // 构建 Dispatcher
        Dispatcher dispatcher = new Dispatcher();
        dispatcher.setMaxRequests(config.concurrentGlobal());
        dispatcher.setMaxRequestsPerHost(config.poolMaxPerHost());

        // 构建 OkHttpClient
        this.httpClient = new OkHttpClient.Builder()
                // 超时配置
                .connectTimeout(config.connectTimeout(), TimeUnit.MILLISECONDS)
                .readTimeout(config.readTimeout(), TimeUnit.MILLISECONDS)
                .callTimeout(config.callTimeout(), TimeUnit.MILLISECONDS)

                // 连接池配置
                .connectionPool(connectionPool)
                .dispatcher(dispatcher)

                // 禁用重试机制
                .retryOnConnectionFailure(false)

                // 用户代理和请求头
                .addInterceptor(chain -> {
                    Request request = chain.request().newBuilder()
//                            .header("User-Agent", config.userAgent())
                            .header("Accept", "application/json")
                            .header("Connection", "close")  // 短连接，避免连接复用问题
                            .build();
                    return chain.proceed(request);
                })

                .build();

        LOG.infof("video_parse", "OkHttp客户端初始化完成", "connectTimeout=" + config.connectTimeout() + "ms, readTimeout=" + config.readTimeout() + "ms, callTimeout=" + config.callTimeout() + "ms, globalConcurrent=" + config.concurrentGlobal() + ", perSourceConcurrent=" + config.concurrentPerSource());
    }

    public OkHttpClient getHttpClient() {
        return httpClient;
    }

    public Semaphore getGlobalSemaphore() {
        return globalSemaphore;
    }

    public Semaphore getSourceSemaphore(String sourceCode) {
        return sourceSemaphores.computeIfAbsent(sourceCode,
                k -> new Semaphore(config.concurrentPerSource()));
    }
} 